22 字节-国际化广告创意与品牌
> Last Format Time:6/12/2026 21:03:57
6/12/26 【理由】原文将「一面」「二面」并列写成 H1,且 ## 提问 与 ### CSS 动画... 层级混乱。 原内容:# 一面 / # 二面;### CSS 动画:transition vs animation 紧贴在 ## 提问 下方
一面
6/10/26
提问
主要围绕着项目进行提问,包括但不限于:
- 控制版面、权限怎么做的,spec
- 分片下载,你们的分页下载是什么做的
- 有关hooks的:你在项目中的hooks使用经验是什么
- css:position、动画两种一种是过渡一种是animation(这个不会)
CSS 动画:transition vs animation
你之前不会,现在必须理解并能说清楚。
| 特性 | transition | animation |
|---|---|---|
| 触发方式 | 需要状态改变(:hover、类名切换、JS 修改) | 自动执行,无需交互 |
| 循环控制 | 一般执行一次(可配合 transitionend 循环) | 通过 animation-iteration-count 无限循环 |
| 关键帧 | 只有起始和结束两个状态 | 可定义多个关键帧(@keyframes) |
| 精细控制 | 较简单,仅变化一个属性 | 可以每个阶段改变多个属性、设置不同 easing |
| 暂停/播放 | 无法暂停 | 可通过 animation-play-state: paused 暂停 |
| 属性示例 | transition: all 0.3s ease; | animation: slideIn 1s ease-in-out 2; |
| 适用场景 | hover 变色、菜单展开、按钮反馈 | 加载动画、无限旋转、复杂入场/出场效果 |
关键代码对比
/* transition */
.box {
width: 100px;
transition: width 0.5s;
}
.box:hover {
width: 200px;
}
/* animation */
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}
.animated {
animation: bounce 0.6s infinite;
}
code(TS)
- 解释为什么会报错、泛型以及获取元组的第一个类型的函数first()怎么写
- 实现函数:
题目
fs.readFile('/path/index.js', (err, data) => {
// handle err and data
}) ;
const readFile = promisify(fs.readFile);
readFile('/path/index.js').then(data => {
// handle data
}).catch(err => {
// handle err
})
我的实现
function promisify(func) {
return function (url) {
return new Promise((resolve, reject) => {
const cb = (err, data) => {
if (data) {
resolve(data)
} else {
reject(err)
}
}
func(url, cb)
})
}
}
优化后的代码
function promisify(func) {
// 1. 使用 ...args 接收任意数量的参数
return function (...args) {
return new Promise((resolve, reject) => {
const cb = (err, data) => {
// 2. 遵循 error-first 规范,仅通过 err 判断失败
if (err) {
reject(err);
} else {
resolve(data);
}
};
// 3. 将回调函数追加到参数列表末尾
args.push(cb);
// 4. 使用 apply 传递参数并保留 this 上下文
func.apply(this, args);
});
};
}
二面
提问
问了业务的具体细节,落实到具体的API了,用的什么函数等等
code
然后就是两道编程题
const viewportWidth = window.innerWidth;
const viewportHeight = window.innerHeight;
console.log(`视口宽度: ${viewportWidth}px, 视口高度: ${viewportHeight}px`);
// 用react hooks实现一个防抖函数
function useDebounce(func, time) {
let timer = null
return function (...args) {
if (!timer) {
setTimeout(() => {
func(args)
clearTimeout(timer)
timer = null
}, time)
}
}
}
解析模板字符串我的实现,共两个
// tpl(
// 'Hello, ${user.name} !' ,
// { user: { name: 'Hanmeimei' } }
// )
function tpl(str, obj) {
if (str.length === 0) return ''
if (obj === null && typeof obj !== "object") return new Error('obj is not a object!!!')
const n = str.length
let start = 0
let end = n - 1
while (start < end) {
console.log(start, end)
if (start !== '{') start++
if (end !== '}') end--
}
console.log(start, end)
let path = str.slice(start, end + 1).split('.')
console.log(path, 'path')
let value = obj
for(let i = 0 ;i< path.length;i++){
value = value[path[i]]
}
let ans = str.slice(0, start - 1) + value + str.slice(end + 1, n)
return ans
}
tpl('Hello, ${user.name} !', { user: { name: 'Hanmeimei' } })
// =======第二个实现========
// tpl(
// 'Hello, ${user.name} !' ,
// { user: { name: 'Hanmeimei' } }
// )
function tpl(str, obj) {
if (str.length === 0) return ''
if (obj === null && typeof obj !== 'object')
return new Error('obj is not a object!!!')
const n = str.length
let start = str.indexOf('{')
let end = str.indexOf('}')
console.log(start, end)
let path = str.slice(start + 1, end).split('.')
console.log(path, 'path')
let value = obj
for (let i = 0; i < path.length; i++) {
value = value[path[i]]
}
console.log(value);
let ans = str.slice(0, start - 1) + value + str.slice(end + 1, n)
return ans
}
console.log(tpl('Hello, ${user.name} !', { user: { name: 'Hanmeimei' } }))
// Hello, Hanmeimei !
反思
肯定是没有了,凉了。。。
6/12/26 没过二面,结束了